package com.ruoyi.common.utils.sign;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;

import java.lang.reflect.Field;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;

/**
 * @Title: SignMD5Util
 * @Description: 签名相关工具类
 * @Version V1.0
 */

@Slf4j
public class SignMD5Util {
    /**
     * 获取签名的util
     *
     * @param map       请求参数
     * @param secretKey 密钥
     * @return
     */
    public static String getSpeedPaySign(Map<String, String> map, String secretKey) {

        if (map.size() == 0) {
            return "";
        }

        StringBuffer sb = new StringBuffer("");

        Set<String> keySet = map.keySet();
        Iterator<String> iter = keySet.iterator();
        while (iter.hasNext()) {
            String key = iter.next();
            if (StrUtil.isNotBlank(map.get(key))) {
                sb.append("&" + key + "=" + map.get(key));
            }
        }
        sb.deleteCharAt(0);

        String signStr = "";
        signStr = sb.toString() + "&secret=" + secretKey;


        return MD5(signStr).toUpperCase();
    }


    /**
     * 获取签名的util
     *
     * @param map       请求参数
     * @param secretKey 密钥
     * @return
     */
    public static String getSignStr(Map<String, String> map, String secretKey) {

        if (map.size() == 0) {
            return "";
        }

        StringBuffer sb = new StringBuffer("");

        Set<String> keySet = map.keySet();
        Iterator<String> iter = keySet.iterator();
        while (iter.hasNext()) {
            String key = iter.next();
            if (StrUtil.isNotBlank(map.get(key))) {
                sb.append("&" + key + "=" + map.get(key));
            }

        }
        sb.deleteCharAt(0);
        return sign(sb.toString(), secretKey);
    }


    public static String sign(String content, String key) {
        String signStr = "";
        signStr = content + "&key=" + key;
        //MD5加密后，字符串所有字符转换为大写
        return MD5(signStr).toUpperCase();
    }

    public static String sign1(String content, String key) {
        String signStr = "";
        signStr = content + "&key=" + key;
        //MD5加密后，字符串所有字符转换为大写
        return MD5(signStr);
    }

    /**
     * MD5加密算法
     *
     * @param s
     * @return
     * @see [类、类#方法、类#成员]
     */
    public final static String MD5(String s) {
        char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
        try {
            byte[] btInput = s.getBytes("utf-8");
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            mdInst.update(btInput);
            byte[] md = mdInst.digest();
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str).toLowerCase();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String getSign(Map<String, String> map, String secretKey) {

        if (map.size() == 0) {
            return "";
        }

        StringBuffer sb = new StringBuffer("");

        Set<String> keySet = map.keySet();
        Iterator<String> iter = keySet.iterator();
        while (iter.hasNext()) {
            String key = iter.next();
            if(StrUtil.isBlank(map.get(key))){
                continue;
            }
            sb.append("&" + key + "=" + map.get(key));
        }
        sb.deleteCharAt(0);
        return sign1(sb.toString(), secretKey);
    }

    //开心果签名
    public static String getPistachioSign(Map<String, String> map, String ts, String secretKey) {

        if (map.size() == 0) {
            return "";
        }

        StringBuffer sb = new StringBuffer("");

        Set<String> keySet = map.keySet();
        Iterator<String> iter = keySet.iterator();
        while (iter.hasNext()) {
            String key = iter.next();
            sb.append("&" + key + "=" + map.get(key));
        }
        sb.deleteCharAt(0);
        String string = sb.toString() + "&ts=" + ts + "&key=" + secretKey;
        String result = md5(string);


        return result;

    }


    public static String upper32(String str) {
        try {


            //结果字符串
            String result = "";
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(str.getBytes());
            byte b[] = md.digest();
            int i;

            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }
            result = buf.toString();
            return result.toUpperCase();
        } catch (Exception e) {

        }
        return null;

    }

    public static void main(String[] args) {

        String s = "action=QueryOrder&mer_no=13888888888&trade_no=B20150124124122159875103&ts=20210621131542&key=12530D183E5DAB2A1FDBDAC497975B4F";
        String s1 = md5(s);
        System.out.println(s1);
    }

    public static String getParam(Map<String, String> map) {

        if (map.size() == 0) {
            return "";
        }

        StringBuffer sb = new StringBuffer("");

        Set<String> keySet = map.keySet();
        Iterator<String> iter = keySet.iterator();
        while (iter.hasNext()) {
            String key = iter.next();
            sb.append("&" + key + "=" + map.get(key));
        }
        sb.deleteCharAt(0);
        return sb.toString();
    }

    public static String getNigeria(String param) {

        String sign = DigestUtils.md5Hex(param);
        return sign;
    }


    public static String getNigeria(String appId, String token, String key, String orderNo, String totalfee) {

        String sign = DigestUtils.md5Hex(appId + token + key + orderNo + totalfee);
        return sign;
    }

    public static String getNigeria1(String appId, String token, String key, String orderNo, String totalfee,
                                     String collectionAccount, String collectionName, String collectionAccountType,
                                     String payIssueWay) {

        String sign = DigestUtils.md5Hex(appId + token + key + orderNo + totalfee + collectionAccount + collectionName + collectionAccountType + payIssueWay);
        return sign;
    }


    ///商户签名

    public static void checkSign(Object apiDto, String secertKey) {
        String sign = getSerSign(apiDto, secertKey);
        JSONObject jsonObject = JSONUtil.parseObj(apiDto);
        String merchSign = jsonObject.getStr("sign");
        if (!StrUtil.equals(sign, merchSign)) {
            log.info("商户签名数据:{}",JSONUtil.parseObj(apiDto));
            throw new RuntimeException("Signature error");
        }
    }

    //    //本地签名
//    public static String getSerSign(ApiDto apiDto, String secertKey) {
//        //一套签名
//        TreeMap<String, String> map = SignMD5Util.objToMap(apiDto);
//        map.remove("sign");
//       return SignMD5Util.getSignStr(map, secertKey);
//
//    }
//本地签名
    public static String getSerSign(Object apiDto, String secertKey) {
        //一套签名
        TreeMap<String, String> map = SignMD5Util.objToMap(apiDto);
        map.remove("sign");
        return SignMD5Util.bxk11Sign(map, secertKey);

    }

    /**
     * 将对象转成TreeMap,属性名为key,属性值为value
     *
     * @param object 对象
     * @return
     * @throws IllegalAccessException
     */
    public static TreeMap<String, String> objToMap(Object object) {
        try {
            Class clazz = object.getClass();
            TreeMap<String, String> treeMap = new TreeMap<String, String>();
            while (null != clazz.getSuperclass()) {
                Field[] declaredFields1 = clazz.getDeclaredFields();

                for (Field field : declaredFields1) {
                    String name = field.getName();
                    // 获取原来的访问控制权限
                    boolean accessFlag = field.isAccessible();
                    // 修改访问控制权限
                    field.setAccessible(true);
                    Object value = field.get(object);
                    // 恢复访问控制权限
                    field.setAccessible(accessFlag);
                    if (null != value && StrUtil.isNotBlank(value.toString())) {
                        //如果是List,将List转换为json字符串
                        if (value instanceof List) {
                            value = JSONUtil.toJsonStr(value);
                            //  value = JSON.toJSONString(value);
                        }
                        treeMap.put(name, value.toString());
                    }
                }

                clazz = clazz.getSuperclass();
            }
            return treeMap;
        } catch (Exception e) {

        }
        return null;
    }

    public static String bxk11Sign(Map<String, String> map, String secretKey) {

        if (map.size() == 0) {
            return "";
        }
        StringBuffer sb = new StringBuffer("");

        Set<String> keySet = map.keySet();
        Iterator<String> iter = keySet.iterator();
        while (iter.hasNext()) {
            String key = iter.next();
            if (StrUtil.isNotBlank(map.get(key))) {
                sb.append("&" + key + "=" + map.get(key));
            }
            // sb.append("&" + key + "=" + map.get(key));
        }
        sb.deleteCharAt(0);
        String signStr = "";
        signStr = sb.toString() + "&key=" + secretKey;
        //MD5加密后，字符串所有字符转换为大写
        return md5(signStr);

    }

    public static String india2Sign(Map<String, String> map, String secretKey) {

        if (map.size() == 0) {
            return "";
        }
        StringBuffer sb = new StringBuffer("");

        Set<String> keySet = map.keySet();
        Iterator<String> iter = keySet.iterator();
        while (iter.hasNext()) {
            String key = iter.next();
            sb.append("&" + key + "=" + map.get(key));
        }
        sb.deleteCharAt(0);
        String signStr = "";
        signStr = sb.toString() + "&key=" + secretKey;
        //MD5加密后，字符串所有字符转换为小写
        return MD5(signStr).toLowerCase();

    }

    public static String turkeySign(Map<String, String> map, String secretKey) {

        if (map.size() == 0) {
            return "";
        }
        StringBuffer sb = new StringBuffer("");

        Set<String> keySet = map.keySet();
        Iterator<String> iter = keySet.iterator();
        while (iter.hasNext()) {
            String key = iter.next();
            sb.append("&" + key + "=" + map.get(key));
        }
        sb.deleteCharAt(0);
        String signStr = "";
        signStr = sb.toString() + secretKey;
        //MD5加密后，字符串所有字符转换为小写
        return MD5(signStr).toLowerCase();

    }


    ////巴西k11
    public static String md5(String str) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(str.getBytes());
            byte[] byteDigest = md.digest();
            int i;
            //字符数组转换成字符串
            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < byteDigest.length; offset++) {
                i = byteDigest[offset];
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }
            // 32位加密
            return buf.toString().toUpperCase();
            // 16位的加密
            //return buf.toString().substring(8, 24).toUpperCase();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }


    public static String philippinesSin(Map<String, String> map, String secretKey) {

        if (map.size() == 0) {
            return "";
        }
        StringBuffer sb = new StringBuffer("");

        Set<String> keySet = map.keySet();
        Iterator<String> iter = keySet.iterator();
        while (iter.hasNext()) {
            String key = iter.next();
            sb.append("&" + key + "=" + map.get(key));
        }
        sb.deleteCharAt(0);
        String signStr = "";
        signStr = sb.toString() + "&key=" + secretKey;
        return calculate(signStr);

    }

    private static String calculate(String signSource) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(signSource.getBytes("utf-8"));
            byte[] b = md.digest();

            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < b.length; offset++) {
                int i = b[offset];
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }
            return buf.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    public static String getStr(Map<String, String> map, String sign) {
        Set<String> keySet = map.keySet();
        Iterator<String> iter = keySet.iterator();
        StringBuffer sb = new StringBuffer();
        while (iter.hasNext()) {
            String key = iter.next();
            sb.append("&" + key + "=" + map.get(key));

        }
        sb.deleteCharAt(0);
        String str = sb + "&sign=" + sign;
        return str;

    }
}

